package com.ifnk.portaljava.hlyt.etl;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.*;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * <p>Title:类 </p>
 *
 * <p>Description: 定时检测指定目录里是否有文件，若有则调用插入数据库，如果有浏览器查询，则同时将数据发往相应浏览器</p>
 *
 * <p>Copyright: Copyright (c) 2010</p>
 *
 * <p>Company: </p>
 * 
 * @author chengzhang.shi.hlyt@gmail.com
 * @version 1.0
 */
public class PoolThread extends Thread {

	private int sleepTime = 5000;
	
	private Properties prop;
	private File dataDir;
	private File workDir;
	private File backupDir;
	private Log loger = LogFactory.getLog(this.getClass());
	
	private ExecutorService pool = Executors.newCachedThreadPool();
	private ExecutorService etlPool = Executors.newCachedThreadPool();
	
	private Map<String, Date> clientMap = new HashMap<String, Date>();
	
	private static PoolThread self;
	
	static {
		self = new PoolThread();
		self.setProp();
		self.setSleepTime(1000);
		self.start();
	}
	
	private PoolThread() {
		
	}
	
	public static PoolThread getInstance() {
		return self;
	}
	
	public void setProp() {
		
		prop = new Properties();
		try {
			prop.load(PoolThread.class.getClassLoader().getResourceAsStream("etl.properties"));
			dataDir = new File(prop.getProperty("dataDir"));
			workDir = new File(prop.getProperty("workDir"));
			backupDir = new File(prop.getProperty("backupDir"));
			workDir.mkdirs();
			backupDir.mkdirs();

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void run() {
		while (true) {
			try {
				List<File> files = getNormalFile(dataDir);
				if(files != null && files.size() != 0) {
					InsertDataMultiThread task = new InsertDataMultiThread();
					File insertDir = new File(workDir.getPath() + File.separator + task.hashCode() + File.separator);
					insertDir.mkdirs();
					copyAllFile(files, insertDir);
					task.setWorkDir(insertDir);
					task.setBackupDir(backupDir);
					checkClients();
					if(!clientMap.isEmpty()) {
						DataToFlexTask etlTask = new DataToFlexTask();
						String[] a = {""};
						etlTask.setClientIds((String[])clientMap.keySet().toArray(a));
						File etlDir = new File(workDir.getPath() + File.separator + etlTask.hashCode() + File.separator);
						etlDir.mkdirs();
						copyAllFile(files, etlDir);
						etlTask.setWorkDir(etlDir);
						etlPool.execute(etlTask);
					}
					deleteAllFile(files);
					pool.execute(task);
				}
//				Thread.currentThread().
				sleep(sleepTime);
			} catch (InterruptedException e) {
				loger.error(e);
			} catch (Exception e) {
				loger.error(e);
			}
		}
	}
	/**
	 * 删除过期的clientId
	 */
	private void checkClients() {
		Iterator<String> iterator = clientMap.keySet().iterator();
		while(iterator.hasNext()) {
			String key = iterator.next();
			if((new Date().getTime() - clientMap.get(key).getTime()) > 60000) {
				iterator.remove();
			}
		}
	}
	
	private int n = 0;
	private List<File> getNormalFile(File dir) {
		List<File> filesList = null;
		if(dir.isDirectory()) {
			n = 0;
			filesList = Arrays.asList(dir.listFiles());
			for(int i = 0; i < filesList.size(); i++) {
				if(!filesList.get(i).isFile()) {
					filesList.remove(i);
				}
			}
		} else {
			if(n < 3) {
				n++;
				loger.error(dir.getPath() + " 不是目录！");
			}
		}
		return filesList;
	}
	
	private int copyAllFile(List<File> sources, File destination) {
		int num = 0;
		Iterator<File> fileIter = sources.iterator();
		if(destination.isDirectory()) {
			File file = null;
			while(fileIter.hasNext()) {
				file = fileIter.next();
				if (file.isDirectory()) {
					continue;
				}
				copyFile(file, new File(destination.getPath() + File.separator + file.getName()));
				num++;
			}
		} else {
			loger.error("copyAllFile:" + destination.getPath() + "不是目录！");
		}
		return num;
	}

	private int deleteAllFile(List<File> sources) {
		int num = 0;
		Iterator<File> fileIter = sources.iterator();
		File file = null;
		while(fileIter.hasNext()) {
			file = fileIter.next();
			if(file.isDirectory()) {
				continue;
			}
			deleteFile(file);
			num++;
		}
		return num;
	}
	
	private void copyFile(File source, File destination) {
		FileInputStream fis = null;
		FileOutputStream fos = null;
		try {
			fis = new FileInputStream(source);
			fos = new FileOutputStream(destination);
			byte[] buff = new byte[1024];
			int readed = -1;
			while ((readed = fis.read(buff)) != -1) {
				fos.write(buff, 0, readed);
			}
			loger.info("文件" + source.getAbsolutePath() + "拷贝到" + destination.getAbsolutePath() + "完成。");
		} catch (FileNotFoundException e) {
			loger.error("文件" + source.getAbsolutePath() + "拷贝到" + destination.getAbsolutePath() + "出错！" + e);
			e.printStackTrace();
		} catch (IOException e) {
			loger.error("文件" + source.getAbsolutePath() + "拷贝到" + destination.getAbsolutePath() + "出错！" + e);
			e.printStackTrace();
		} finally {
			if (fis != null) {
				try {
					fis.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (fos != null) {
				try {
					fos.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private void deleteFile(File file) {
		boolean isDeleted = file.delete();
		if (isDeleted) {
			loger.info("删除文件" + file.getAbsolutePath() + "成功。");
		} else {
			loger.error("删除文件" + file.getAbsolutePath() + "失败！");
		}
	}
	
	public void start(String clientId) {
		clientMap.put(clientId, new Date());
	}
	
	public void stop(String clientId) {
		clientMap.remove(clientId);
	}
	
	public void updateClient(String clientId, Date date) {
		clientMap.put(clientId, date);
	}
	
	public int getSleepTime() {
		return sleepTime;
	}

	public void setSleepTime(int sleepTime) {
		this.sleepTime = sleepTime;
	}
	
	
}
